/**
 * 
 */
package com.nari.heatshare.dao;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.nari.coreframe.dao.hibernate3.GenericDaoImpl;
import com.nari.ftpclient.business.IRemoteFileManage;
import com.nari.heatshare.model.IAssignMeterDataGather;
import com.nari.heatshare.model.IGprsUploadTrace;
import com.nari.heatshare.model.IHeatMeterDataGather;
import com.nari.heatshare.model.ITemperaturePointDataGather;
import com.nari.heatshare.utils.MeterDataTxtGenerator;
import com.nari.platform.date.CalendarUtils;

/**
 * 
 * @author Xiaopeng
 * @date 2014-5-7
 */
public class GprsUploadTraceDaoImpl extends GenericDaoImpl<IGprsUploadTrace, String> 
		implements IGprsUploadTraceDao {
	private static final int BUFFER_SIZE = 20*1024; //设置文件上传缓存20K
	private String diskFilePath;
	private String gprsDebugFolder;
	private IRemoteFileManage iRemoteFileManage;
	
	/**
	 * 保存上传文件到指定的目录中
	 * @param src 源上传缓存文件
	 * @param dest 目标保存文件
	 * @return
	 * @throws Exception 返回上传结果标志位
	 * @author Xiaopeng
	 * @date 2013-10-28
	 */
	public int saveUpload(File src, File dest) throws Exception {
		BufferedOutputStream bos = 
				new BufferedOutputStream(new FileOutputStream(dest), BUFFER_SIZE);
		BufferedInputStream bis = 
				new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE);
		int length;
		byte[] buffer = new byte[BUFFER_SIZE];
		while((length=bis.read(buffer))!=-1){
			bos.write(buffer, 0, length);
		}
		bos.close();
		bis.close();
		return 1;
	}
	
	/**
	 * 通过文件映射唯一标识删除GPRS上传痕迹信息
	 * @param uploadTraceUID
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-12
	 */
	public void deleteTraceFileByUID(String uploadTraceUID) throws Exception {
		IGprsUploadTrace gprsUploadTrace = this.queryEntityById(uploadTraceUID);
		if(gprsUploadTrace != null) {
			//删除磁盘附件
			File attachFile = new File(gprsUploadTrace.getDiskID() + "/" + gprsUploadTrace.getSavePath());
			if(attachFile.exists()) attachFile.delete();
			//删除文件映射
			this.deleteEntityById(uploadTraceUID);
			//删除FTP服务器存储的远程文件
			iRemoteFileManage.removeRemoteFile("", gprsUploadTrace.getSvFilename()+"."+gprsUploadTrace.getFileType());
		}
	}
	
	/**
	 * 通过上传批次信息查询对应GPRS上传痕迹
	 * @param batchStatisUid
	 * @param uploadDataType
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-5-7
	 */
	public IGprsUploadTrace queryTraceInfoByBatchUID(String batchStatisUid, 
			Integer uploadDataType) throws Exception {
		String hsql = "from IGprsUploadTrace gut " +
				"where gut.batchStatisUid='"+batchStatisUid+"' " +
				"and gut.uploadDataType=" + uploadDataType;
		List<IGprsUploadTrace> traceList = this.runQueryHSql(hsql);
		IGprsUploadTrace gprsUploadTrace = null;
		if(traceList!=null && traceList.size()>0) {
			gprsUploadTrace = traceList.get(0);
		}
		return gprsUploadTrace;
	}
	
	/**
	 * 分配表数据GPRS上传任务原始数据的痕迹生成
	 * @param meterDataList
	 * @param batchStatisUid
	 * @param concentratorNo
	 * @param recordTime
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-5-7
	 */
	public void saveAmdGprsUploadTraceFile(List<IAssignMeterDataGather> meterDataList, 
			String batchStatisUid, String concentratorNo, Date recordTime) throws Exception {
		//调试痕迹文件
		File txtTraceFile = null;
		//查询系统已存痕迹文件
		IGprsUploadTrace gprsUploadTrace = this.queryTraceInfoByBatchUID(batchStatisUid, 1);
		if(gprsUploadTrace != null) {
			txtTraceFile = new File(gprsUploadTrace.getDiskID() + "/" + gprsUploadTrace.getSavePath());
		} else {
			//附件存储路径对应的磁盘目录检测
			File fileSaveFolder = new File(this.diskFilePath + "/" + this.gprsDebugFolder);
			if(!fileSaveFolder.exists()) fileSaveFolder.mkdirs();
			//痕迹文件名称
			String orFilename = concentratorNo + "_" + CalendarUtils.parseDateToString(recordTime);
			//痕迹文件存储名
			String svFilename = "amdGprsTrace_" 
						+ batchStatisUid + "_"
						+ concentratorNo + "_"
						+ CalendarUtils.parseDateToString(recordTime);
			//文件的存储路径(相对路径)
			String savePath = this.gprsDebugFolder + "/" + svFilename + ".TXT";
			//痕迹文件初始化
			txtTraceFile = new File(diskFilePath + "/" + savePath);
			//痕迹信息初始化
			gprsUploadTrace = new IGprsUploadTrace();
			gprsUploadTrace.setBatchStatisUid(batchStatisUid);
			gprsUploadTrace.setUploadDataType(1);
			gprsUploadTrace.setOrFilename(orFilename);
			gprsUploadTrace.setSvFilename(svFilename);
			gprsUploadTrace.setDiskID(diskFilePath);
			gprsUploadTrace.setSavePath(savePath);
			gprsUploadTrace.setFileType("TXT");
			gprsUploadTrace.setCreateTime(new Date());
			this.saveEntity(gprsUploadTrace);
		}
		//调试文件生成或更新
		RandomAccessFile txtFile = null;
		try {
			txtFile = new RandomAccessFile(txtTraceFile, "rw");
			//设置指定位置写入数据
			txtFile.seek(txtTraceFile.length());
			if(meterDataList!=null && meterDataList.size()>0) {
				StringBuffer updateInfo = new StringBuffer("\n\n");
				updateInfo.append("==========");
				updateInfo.append("集中器号：" + concentratorNo);
				updateInfo.append("\t");
				updateInfo.append("抄表时间：" + CalendarUtils.parseDateTimeToString(recordTime));
				updateInfo.append("\t");
				updateInfo.append("更新时间：" + CalendarUtils.parseDateTimeToString(new Date()));
				updateInfo.append("==========");
				updateInfo.append("\n");
				txtFile.write(updateInfo.toString().getBytes());
				for(int index=0; index<meterDataList.size(); index++) {
					IAssignMeterDataGather meterData = meterDataList.get(index);
					//拼接热表数据字符串
					String meterDataDebugInfo = MeterDataTxtGenerator.genAssignMeterDataRecord(meterData);
					if(index < meterDataList.size()-1) {
						meterDataDebugInfo += "\n";
					}
					txtFile.writeBytes(meterDataDebugInfo.toString());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.getMessage());
		} finally {
			if(txtFile != null) txtFile.close();
			//将痕迹文件存储到FTP服务器
			iRemoteFileManage.uploadFile("", gprsUploadTrace.getSvFilename()+"."+gprsUploadTrace.getFileType(), gprsUploadTrace.getDiskID()+"/"+gprsUploadTrace.getSavePath());
		}
	}
	
	/**
	 * 查询上传任务批次数据与痕迹文件UID的映射表
	 * @param batchStatisUIDList 上传任务批次数据UID列表
	 * @param uploadDataType 上传任务批次的数据类型
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-5-8
	 */
	public Map<String, String> queryReferBatchStatisMap(List<String> batchStatisUIDList, 
			Integer uploadDataType) throws Exception {
		Map<String, String> referUIDMap = new HashMap<String, String>();
		if(batchStatisUIDList!=null && batchStatisUIDList.size()>0) {
			StringBuffer hsql = new StringBuffer("select distinct gut.batchStatisUid,gut.id ");
			hsql.append("from IGprsUploadTrace gut ");
			hsql.append("where gut.batchStatisUid in(");
			for (int index = 0; index < batchStatisUIDList.size(); index++) {
				hsql.append("'");
				hsql.append(batchStatisUIDList.get(index));
				hsql.append("'");
				if (index < batchStatisUIDList.size() - 1) {
					hsql.append(",");
				}
			}
			hsql.append(") ");
			//批次数据类型
			hsql.append("and gut.uploadDataType="+uploadDataType);
			List<Object> resultsList = this.runQueryHSqlObject(hsql.toString());
			// 格式化查询结果集
			if (resultsList != null && resultsList.size() > 0) {
				for (Object result : resultsList) {
					Object[] arrayMap = (Object[]) result;
					referUIDMap.put(arrayMap[0].toString(), arrayMap[1].toString());
				}
			}
		}
		return referUIDMap;
	}
	
	/**
	 * 热量表数据GPRS上传任务原始数据的痕迹生成
	 * @param meterDataList
	 * @param batchStatisUid
	 * @param concentratorNo
	 * @param recordTime
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-5-7
	 */
	public void saveHmdGprsUploadTraceFile(List<IHeatMeterDataGather> meterDataList, 
			String batchStatisUid, String concentratorNo, Date recordTime) throws Exception {
		
	}
	
	/**
	 * 温度点数据GPRS上传任务原始数据的痕迹生成
	 * @param meterDataList
	 * @param batchStatisUid
	 * @param concentratorNo
	 * @param recordTime
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-5-7
	 */
	public void saveTpdGprsUploadTraceFile(List<ITemperaturePointDataGather> meterDataList, 
			String batchStatisUid, String concentratorNo, Date recordTime) throws Exception {
		
	}

	/**
	 * @return the diskFilePath
	 */
	public String getDiskFilePath() {
		return diskFilePath;
	}

	/**
	 * @param diskFilePath the diskFilePath to set
	 */
	public void setDiskFilePath(String diskFilePath) {
		this.diskFilePath = diskFilePath;
	}

	/**
	 * @return the gprsDebugFolder
	 */
	public String getGprsDebugFolder() {
		return gprsDebugFolder;
	}

	/**
	 * @param gprsDebugFolder the gprsDebugFolder to set
	 */
	public void setGprsDebugFolder(String gprsDebugFolder) {
		this.gprsDebugFolder = gprsDebugFolder;
	}

	/**
	 * @return the iRemoteFileManage
	 */
	public IRemoteFileManage getiRemoteFileManage() {
		return iRemoteFileManage;
	}

	/**
	 * @param iRemoteFileManage the iRemoteFileManage to set
	 */
	public void setiRemoteFileManage(IRemoteFileManage iRemoteFileManage) {
		this.iRemoteFileManage = iRemoteFileManage;
	}

}
